#ifndef __MY_CAN
#define __MY_CAN

#include "main.h"
#include "stdbool.h"
#include "crc_tools.h"
#include "service.h"
#include "can_message_handlers.h"
#include "string.h"

// 帧类型枚举
typedef enum {
  CAN_FRAME_TYPE_INIT = 0x01,
  CAN_FRAME_TYPE_TARGET_POSITION = 0x02,
  CAN_FRAME_TYPE_TARGET_TORQUE = 0x03,
  CAN_FRAME_TYPE_STATUS = 0x04,
  CAN_FRAME_TYPE_POSITION = 0x05,
  CAN_FRAME_TYPE_ELECTRIC_ANGLE = 0x06,
  CAN_FRAME_TYPE_VD = 0x07,
  CAN_FRAME_TYPE_IQ = 0x08,
  CAN_FRAME_TYPE_QUERY = 0x09
} FrameType;

// 控制模式枚举
typedef enum
{
  CONTROL_MODE_ABSOLUTE = 0x00, // 绝对位置
  CONTROL_MODE_RELATIVE = 0x01  // 相对位置
} ControlMode;

// 力矩控制模式枚举
typedef enum
{
  TORQUE_MODE_CLOSED_LOOP = 0x00, // 闭环控制 (控制电流)
  TORQUE_MODE_OPEN_LOOP = 0x01    // 开环控制 (控制电压)
} TorqueControlMode;

// 状态枚举
typedef enum
{
  STATUS_UNINITIALIZED = 0x00, // 未初始化
  STATUS_INITIALIZING = 0x01,  // 初始化中
  STATUS_INITIALIZED = 0x02,   // 初始化完成
  STATUS_FAULT = 0x03          // 故障
}Status;

// 故障码枚举
typedef enum {
  FAULT_CODE_OTHER = 0x00,       // 其它故障
  FAULT_CODE_ABZ_ENCODER = 0x01, // ABZ编码器故障
  FAULT_CODE_HALL_SENSOR = 0x02,// 霍尔传感器故障
  FAULT_CODE_ABS_ENCODER = 0x03,// 绝对编码器故障
  FAULT_CODE_OVERLOAD = 0x04    // 驱动器过载故障
} FaultCode;

// 编码器类型枚举
typedef enum {
    ENCODER_TYPE_UNKNOWN = 0x00, // 未知编码器
    ENCODER_TYPE_ABZ = 0x01,     // ABZ编码器
    ENCODER_TYPE_ABS = 0x02      // 绝对编码器
} EncoderType;

// 初始化帧
typedef struct
{
  FrameType frame_type;
  uint8_t motor_id;       // 电机编号
  float target_position;  // 32 位浮点数，单位：弧度
  uint8_t control_mode;   // 0x00: 绝对位置， 0x01: 相对位置
  uint8_t crc;
} CAN_InitFrame;

// 位置指令帧
typedef struct
{
  FrameType frame_type;
  uint8_t motor_id;       // 电机编号
  float target_position;  // 32 位浮点数，单位：弧度
  uint8_t control_mode;   // 0x00: 绝对位置， 0x01: 相对位置
  uint8_t crc;
} CAN_PositionFrame;

// 力矩指令帧
typedef struct
{
  uint8_t frame_type;
  uint8_t motor_id;       // 电机编号
  float target_torque;    // 电流或电压值
  uint8_t control_mode;   // 0x00: 闭环控制, 0x01: 开环控制
  uint8_t crc;
} CAN_TorqueFrame;;

// 状态帧
typedef struct {
  FrameType frame_type;
  uint8_t motor_id;            // 电机编号
  Status status;
  FaultCode fault_code;
  uint8_t reserved1;
  uint8_t reserved2;
  uint8_t reserved3;
  uint8_t crc;                 // CRC校验位
} CAN_StatusFrame;

// 实时位置帧
typedef struct {
  FrameType frame_type;
  uint8_t motor_id;            // 电机编号
  float real_position;         // 32位浮点数，单位：弧度
  EncoderType encoder_type;
  uint8_t crc;                 // CRC校验位
} CAN_RealPositionFrame;

// 电角度帧
typedef struct {
  FrameType frame_type;
  uint8_t motor_id;            // 电机编号
  float electric_angle;        // 32位浮点数，单位：弧度
  uint8_t reserved1;
  uint8_t crc;                 // CRC校验位
} CAN_ElectricAngleFrame;

// Vd帧
typedef struct {
  FrameType frame_type;
  uint8_t motor_id;            // 电机编号
  float Vd;                    // 32位浮点数
  uint8_t reserved1;
  uint8_t crc;                 // CRC校验位
} CAN_VdFrame;

// Iq帧
typedef struct {
  FrameType frame_type;
  uint8_t motor_id;            // 电机编号
  float Iq;                    // 32位浮点数
  uint8_t reserved1;
  uint8_t crc;                 // CRC校验位
} CAN_IqFrame;

// 查询帧
typedef struct {
  FrameType frame_type;
  uint8_t motor_id;            // 电机编号
  float query_value;           // 32位浮点数
  uint8_t reserved1;
  uint8_t reserved2;
  uint8_t crc;                 // CRC校验位
} CAN_QueryFrame;

// 打包
void can_pack_frame(uint8_t* buffer, const void* frame, size_t size);

// 解包
bool can_unpack_frame(void* frame, const uint8_t* buffer, size_t size);

void process_can_message(FDCAN_MessageTypeDef* message);

#endif // !__MY_CAN
